<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<meta name="keywords" content="spring,Spring,java,web,程序员,博客,IT,技术,移动开发,Web前端,企业架构,编程语言,互联网,数据库,技术博客,blog,分布式架构,分布式">
		<meta name="description" content="cdcoder是一个程序员学习交流平台，深度IT技术博客，移动开发博客,Web前端博客,企业架构博客,编程语言博客,互联网博客,数据库博客,IT blog,核心关注IT知识传播，共享。为更好的IT产业贡献一份微薄的力量。">
			<link rel="shortcut icon" href="/img/code.ico" />
			<link rel="bookmark"href="/img/code.ico" />
		<title>徐思润个人博客</title>
		<link href="../css/index.css" rel="stylesheet">
		<style>
			body {
				font-size: 16px;
				font: 400 16px/1.62 Georgia, "Xin Gothic", "Hiragino Sans GB", "Droid Sans Fallback", "Microsoft YaHei", sans-serif;
				font-family: 'PT serif', 微軟正黑體, 微软雅黑, 华文细黑, Microsoft Yahei, Hiragino Sans GB, sans-serif;
				color: #D0CCCC;

				text-shadow: 0px 0px 1px rgba(24, 22, 22, 0.35);
				background-color: #000;
			}
		</style>
	</head>
	<body>

		<header>
			<div class="logo"><a href="/index.html">徐思润博客</a></div>
			<nav>
				<ul id="starlist">
					<li><a href="/java/index.html">java</a></li>
					<li><a href="/data/index.html">算法与数据结构</a></li>
					<li><a href="/db/mysql.html">数据库</a></li>
					<li><a href="/distribution/index.html">分布式</a></li>
					<li><a href="/framework/index.html">架构</a></li>
					<li><a href="/interview/index.html">面试与被面试</a></li>
					<li><a href="/live/index.html">日常生活</a></li>
					<li><a href="/about.html">关于我</a></li>
					<li><a href="/baby/index.html">baby墙</a></li>
				</ul>
			</nav>
		</header>
		<div class="box">
			<div style="width: 60%;text-align: center;">
						<h1>J2EE基础知识</h1>
			<h2 id="header-n47">Servlet总结</h2>
			<p>在Java Web程序中，<strong>Servlet</strong>主要负责接收用户请求<strong>HttpServletRequest</strong>,在<strong>doGet()</strong>,<strong>doPost()</strong>中做相应的处理，并将回应<strong>HttpServletResponse</strong>反馈给用户。Servlet可以设置初始化参数，供Servlet内部使用。一个Servlet类只会有一个实例，在它初始化时调用<strong>init()方法</strong>，销毁时调用<strong>destroy()方法</strong>。<strong>Servlet需要在web.xml中配置</strong>（MyEclipse中创建Servlet会自动配置），<strong>一个Servlet可以设置多个URL访问</strong>。<strong>Servlet不是线程安全</strong>，因此要谨慎使用类变量。</p>
			<div class="line"></div>
			<h2>阐述Servlet和CGI的区别?</h2>
			<h3>CGI的不足之处:</h3>
			<p>1，需要为每个请求启动一个操作CGI程序的系统进程。如果请求频繁，这将会带来很大的开销。</p>
			<p>2，需要为每个请求加载和运行一个CGI程序，这将带来很大的开销 </p>
			<p>3，需要重复编写处理网络协议的代码以及编码，这些工作都是非常耗时的。</p>
			<h3>Servlet的优点:</h3>
			<p>1，只需要启动一个操作系统进程以及加载一个JVM，大大降低了系统的开销</p>
			<p>2，如果多个请求需要做同样处理的时候，这时候只需要加载一个类，这也大大降低了开销</p>
			<p>3，所有动态加载的类可以实现对网络协议以及请求解码的共享，大大降低了工作量。</p>
			<p>4，Servlet能直接和Web服务器交互，而普通的CGI程序不能。Servlet还能在各个程序之间共享数据，使数据库连接池之类的功能很容易实现。</p>
			<p>补充：Sun
				Microsystems公司在1996年发布Servlet技术就是为了和CGI进行竞争，Servlet是一个特殊的Java程序，一个基于Java的Web应用通常包含一个或多个Servlet类。Servlet不能够自行创建并执行，它是在Servlet容器中运行的，容器将用户的请求传递给Servlet程序，并将Servlet的响应回传给用户。通常一个Servlet会关联一个或多个JSP页面。以前CGI经常因为性能开销上的问题被诟病，然而Fast
				CGI早就已经解决了CGI效率上的问题，所以面试的时候大可不必信口开河的诟病CGI，事实上有很多你熟悉的网站都使用了CGI技术。</p>
			<p>参考：《javaweb整合开发王者归来》P7</p>
			<div class="line"></div>
			<h2>Servlet接口中有哪些方法及Servlet生命周期探秘</h2>
			<p>Servlet接口定义了5个方法，其中<strong>前三个方法与Servlet生命周期相关</strong>：</p>
			<ul>
				<li><strong>void init(ServletConfig config) throws ServletException</strong></li>
				<li><strong>void service(ServletRequest req, ServletResponse resp) throws ServletException, java.io.IOException</strong></li>
				<li><strong>void destory()</strong></li>
				<li>java.lang.String getServletInfo()</li>
				<li>ServletConfig getServletConfig()</li>

			</ul>
			<p><strong>生命周期：</strong> <strong>Web容器加载Servlet并将其实例化后，Servlet生命周期开始</strong>，容器运行其<strong>init()方法</strong>进行Servlet的初始化；请求到达时调用Servlet的<strong>service()方法</strong>，service()方法会根据需要调用与请求对应的<strong>doGet或doPost</strong>等方法；当服务器关闭或项目被卸载时服务器会将Servlet实例销毁，此时会调用Servlet的<strong>destroy()方法</strong>。<strong>init方法和destory方法只会执行一次，service方法客户端每次请求Servlet都会执行</strong>。Servlet中有时会用到一些需要初始化与销毁的资源，因此可以把初始化资源的代码放入init方法中，销毁资源的代码放入destroy方法中，这样就不需要每次处理客户端的请求都要初始化与销毁资源。</p>
			<p>参考：《javaweb整合开发王者归来》P81</p>
			<div class="line"></div>
			<h2>get和post请求的区别</h2>
			<blockquote>
				<p>网上也有文章说：get和post请求实际上是没有区别，大家可以自行查询相关文章！我下面给出的只是一种常见的答案。</p>
			</blockquote>
			<p>①get请求用来从服务器上获得资源，而post是用来向服务器提交数据；</p>
			<p>②get将表单中数据按照name=value的形式，添加到action 所指向的URL
				后面，并且两者使用&quot;?&quot;连接，而各个变量之间使用&quot;&amp;&quot;连接；post是将表单中的数据放在HTTP协议的请求头或消息体中，传递到action所指向URL；</p>
			<p>③get传输的数据要受到URL长度限制（1024字节即256个字符）；而post可以传输大量的数据，上传文件通常要使用post方式；</p>
			<p>④使用get时参数会显示在地址栏上，如果这些数据不是敏感数据，那么可以使用get；对于敏感数据还是应用使用post；</p>
			<p>⑤get使用MIME类型application/x-www-form-urlencoded的URL编码（也叫百分号编码）文本的格式传递参数，保证被传送的参数由遵循规范的文本组成，例如一个空格的编码是&quot;%20&quot;。</p>
			<p>补充：GET方式提交表单的典型应用是搜索引擎。GET方式就是被设计为查询用的。</p>
			 
			<div class="line"></div>
			<h2>什么情况下调用doGet()和doPost()</h2>
			<p>Form标签里的method的属性为get时调用doGet()，为post时调用doPost()。</p>
			<div class="line"></div>
			<h2>转发(Forward)和重定向(Redirect)的区别</h2>
			<p><strong>转发是服务器行为，重定向是客户端行为。</strong></p>
			<p><strong>转发（Forword）</strong>
				通过RequestDispatcher对象的forward（HttpServletRequest request,HttpServletResponse
				response）方法实现的。RequestDispatcher可以通过HttpServletRequest 的getRequestDispatcher()方法获得。例如下面的代码就是跳转到login_success.jsp页面。</p>
			<pre><code class='language-java' lang='java'>     request.getRequestDispatcher(&quot;login_success.jsp&quot;).forward(request, response);
			 </code></pre>
			<p><strong>重定向（Redirect）</strong>
				是利用服务器返回的状态吗来实现的。客户端浏览器请求服务器的时候，服务器会返回一个状态码。服务器通过HttpServletRequestResponse的setStatus(int
				status)方法设置状态码。如果服务器返回301或者302，则浏览器会到新的网址重新请求该资源。 </p>
			<ol>
				<li><strong>从地址栏显示来说</strong></li>

			</ol>
			<p>forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址.
				redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL.</p>
			<ol start='2'>
				<li><strong>从数据共享来说</strong></li>

			</ol>
			<p>forward:转发页面和转发到的页面可以共享request里面的数据.
				redirect:不能共享数据.</p>
			<ol start='3'>
				<li><strong>从运用地方来说</strong></li>

			</ol>
			<p>forward:一般用于用户登陆的时候,根据角色转发到相应的模块.
				redirect:一般用于用户注销登陆时返回主页面和跳转到其它的网站等</p>
			<ol start='4'>
				<li>从效率来说</li>

			</ol>
			<p>forward:高.
				redirect:低.</p>
				<div class="line"></div>
			<h2>自动刷新(Refresh)</h2>
			<p>自动刷新不仅可以实现一段时间之后自动跳转到另一个页面，还可以实现一段时间之后自动刷新本页面。Servlet中通过HttpServletResponse对象设置Header属性实现自动刷新例如：</p>
			<pre><code class='language-java' lang='java'>Response.setHeader(&quot;Refresh&quot;,&quot;1000;URL=http://localhost:8080/servlet/example.htm&quot;);
			 </code></pre>
			<p>其中1000为时间，单位为毫秒。URL指定就是要跳转的页面（如果设置自己的路径，就会实现没过一秒自动刷新本页面一次）</p>
			<div class="line"></div>
			<h2>Servlet与线程安全</h2>
			<p><strong>Servlet不是线程安全的，多线程并发的读写会导致数据不同步的问题。</strong>
				解决的办法是尽量不要定义name属性，而是要把name变量分别定义在doGet()和doPost()方法内。虽然使用synchronized(name){}语句块可以解决问题，但是会造成线程的等待，不是很科学的办法。
				注意：多线程的并发的读写Servlet类属性会导致数据不同步。但是如果只是并发地读取属性而不写入，则不存在数据不同步的问题。因此Servlet里的只读属性最好定义为final类型的。</p>
			<p>参考：《javaweb整合开发王者归来》P92</p>
			 
			<div class="line"></div>
			<h2>JSP和Servlet是什么关系</h2>
			<p>其实这个问题在上面已经阐述过了，Servlet是一个特殊的Java程序，它运行于服务器的JVM中，能够依靠服务器的支持向浏览器提供显示内容。JSP本质上是Servlet的一种简易形式，JSP会被服务器处理成一个类似于Servlet的Java程序，可以简化页面内容的生成。Servlet和JSP最主要的不同点在于，Servlet的应用逻辑是在Java文件中，并且完全从表示层中的HTML分离开来。而JSP的情况是Java和HTML可以组合成一个扩展名为.jsp的文件。有人说，Servlet就是在Java中写HTML，而JSP就是在HTML中写Java代码，当然这个说法是很片面且不够准确的。JSP侧重于视图，Servlet更侧重于控制逻辑，在MVC架构模式中，JSP适合充当视图（view）而Servlet适合充当控制器（controller）。</p>
			<div class="line"></div>
			<h2>JSP工作原理</h2>
			<p>JSP是一种Servlet，但是与HttpServlet的工作方式不太一样。HttpServlet是先由源代码编译为class文件后部署到服务器下，为先编译后部署。而JSP则是先部署后编译。JSP会在客户端第一次请求JSP文件时被编译为HttpJspPage类（接口Servlet的一个子类）。该类会被服务器临时存放在服务器工作目录里面。下面通过实例给大家介绍。
				工程JspLoginDemo下有一个名为login.jsp的Jsp文件，把工程第一次部署到服务器上后访问这个Jsp文件，我们发现这个目录下多了下图这两个东东。
				.class文件便是JSP对应的Servlet。编译完毕后再运行class文件来响应客户端请求。以后客户端访问login.jsp的时候，Tomcat将不再重新编译JSP文件，而是直接调用class文件来响应客户端请求。
				<img src='https://user-gold-cdn.xitu.io/2018/3/31/1627bee073079a28?w=675&h=292&f=jpeg&s=133553' alt='JSP工作原理'
				 referrerPolicy='no-referrer' />
				由于JSP只会在客户端第一次请求的时候被编译 ，因此第一次请求JSP时会感觉比较慢，之后就会感觉快很多。如果把服务器保存的class文件删除，服务器也会重新编译JSP。</p>
			<p>开发Web程序时经常需要修改JSP。Tomcat能够自动检测到JSP程序的改动。如果检测到JSP源代码发生了改动。Tomcat会在下次客户端请求JSP时重新编译JSP，而不需要重启Tomcat。这种自动检测功能是默认开启的，检测改动会消耗少量的时间，在部署Web应用的时候可以在web.xml中将它关掉。</p>
			<p>&nbsp;</p>
			<p>参考：《javaweb整合开发王者归来》P97</p>
			<div class="line"></div>
			<h2>JSP有哪些内置对象、作用分别是什么</h2>
			<p><a href='http://blog.csdn.net/qq_34337272/article/details/64310849'>JSP内置对象 - CSDN博客 </a> </p>
			<p>JSP有9个内置对象：</p>
			<ul>
				<li>request：封装客户端的请求，其中包含来自GET或POST请求的参数；</li>
				<li>response：封装服务器对客户端的响应；</li>
				<li>pageContext：通过该对象可以获取其他对象；</li>
				<li>session：封装用户会话的对象；</li>
				<li>application：封装服务器运行环境的对象；</li>
				<li>out：输出服务器响应的输出流对象；</li>
				<li>config：Web应用的配置对象；</li>
				<li>page：JSP页面本身（相当于Java程序中的this）；</li>
				<li>exception：封装页面抛出异常的对象。</li>

			</ul>
			<div class="line"></div>
			<h2>Request对象的主要方法有哪些</h2>
			<ul>
				<li><pre>setAttribute(String name,Object)</pre>：设置名字为name的request 的参数值 </li>
				<li>getAttribute(String name)：返回由name指定的属性值 </li>
				<li>getAttributeNames()：返回request 对象所有属性的名字集合，结果是一个枚举的实例 </li>
				<li>getCookies()：返回客户端的所有 Cookie 对象，结果是一个Cookie 数组 </li>
				<li>getCharacterEncoding() ：返回请求中的字符编码方式 = getContentLength() ：返回请求的 Body的长度 </li>
				<li>getHeader(String name) ：获得HTTP协议定义的文件头信息 </li>
				<li>getHeaders(String name) ：返回指定名字的request Header 的所有值，结果是一个枚举的实例 </li>
				<li>getHeaderNames() ：返回所以request Header 的名字，结果是一个枚举的实例 </li>
				<li>getInputStream() ：返回请求的输入流，用于获得请求中的数据 </li>
				<li>getMethod() ：获得客户端向服务器端传送数据的方法 </li>
				<li>getParameter(String name) ：获得客户端传送给服务器端的有 name指定的参数值 </li>
				<li>getParameterNames() ：获得客户端传送给服务器端的所有参数的名字，结果是一个枚举的实例 </li>
				<li>getParameterValues(String name)：获得有name指定的参数的所有值 </li>
				<li>getProtocol()：获取客户端向服务器端传送数据所依据的协议名称 </li>
				<li>getQueryString() ：获得查询字符串 </li>
				<li>getRequestURI() ：获取发出请求字符串的客户端地址 </li>
				<li>getRemoteAddr()：获取客户端的 IP 地址 </li>
				<li>getRemoteHost() ：获取客户端的名字 </li>
				<li>getSession([Boolean create]) ：返回和请求相关 Session </li>
				<li>getServerName() ：获取服务器的名字 </li>
				<li>getServletPath()：获取客户端所请求的脚本文件的路径 </li>
				<li>getServerPort()：获取服务器的端口号 </li>
				<li>removeAttribute(String name)：删除请求中的一个属性 </li>

			</ul>
			<div class="line"></div>
			<h2>request.getAttribute()和 request.getParameter()有何区别</h2>
			<p><strong>从获取方向来看：</strong></p>
			<p>getParameter()是获取 POST/GET 传递的参数值；</p>
			<p>getAttribute()是获取对象容器中的数据值；</p>
			<p><strong>从用途来看：</strong></p>
			<p>getParameter用于客户端重定向时，即点击了链接或提交按扭时传值用，即用于在用表单或url重定向传值时接收数据用。</p>
			<p>getAttribute用于服务器端重定向时，即在 sevlet 中使用了 forward 函数,或 struts 中使用了
				mapping.findForward。 getAttribute 只能收到程序用 setAttribute 传过来的值。</p>
			<p>另外，可以用 setAttribute,getAttribute 发送接收对象.而 getParameter 显然只能传字符串。
				setAttribute
				是应用服务器把这个对象放在该页面所对应的一块内存中去，当你的页面服务器重定向到另一个页面时，应用服务器会把这块内存拷贝另一个页面所对应的内存中。这样getAttribute就能取得你所设下的值，当然这种方法可以传对象。session也一样，只是对象在内存中的生命周期不一样而已。getParameter只是应用服务器在分析你送上来的
				request页面的文本时，取得你设在表单或 url 重定向时的值。</p>
			<p><strong>总结：</strong></p>
			<p>getParameter 返回的是String,用于读取提交的表单中的值;（获取之后会根据实际需要转换为自己需要的相应类型，比如整型，日期类型啊等等）</p>
			<p>getAttribute 返回的是Object，需进行转换,可用setAttribute 设置成任意对象，使用很灵活，可随时用</p>
			<h2>include指令include的行为的区别</h2>
			<p><strong>include指令：</strong> JSP可以通过include指令来包含其他文件。被包含的文件可以是JSP文件、HTML文件或文本文件。包含的文件就好像是该JSP文件的一部分，会被同时编译执行。
				语法格式如下：
				&lt;%@ include file=&quot;文件相对 url 地址&quot; %&gt;</p>
			<p>i<strong>nclude动作：</strong> <a href='jsp:include' target='_blank' class='url'>jsp:include</a>动作元素用来包含静态和动态的文件。该动作把指定文件插入正在生成的页面。语法格式如下：
				&lt;jsp:include page=&quot;相对 URL 地址&quot; flush=&quot;true&quot; /&gt;</p>
			<h2>JSP九大内置对象，七大动作，三大指令</h2>
			<p><a href='http://blog.csdn.net/qq_34337272/article/details/64310849'>JSP九大内置对象，七大动作，三大指令总结</a></p>
			<div class="line"></div>
			<h2>讲解JSP中的四种作用域</h2>
			<p>JSP中的四种作用域包括page、request、session和application，具体来说：</p>
			<ul>
				<li><strong>page</strong>代表与一个页面相关的对象和属性。</li>
				<li><strong>request</strong>代表与Web客户机发出的一个请求相关的对象和属性。一个请求可能跨越多个页面，涉及多个Web组件；需要在页面显示的临时数据可以置于此作用域。</li>
				<li><strong>session</strong>代表与某个用户与服务器建立的一次会话相关的对象和属性。跟某个用户相关的数据应该放在用户自己的session中。</li>
				<li><strong>application</strong>代表与整个Web应用程序相关的对象和属性，它实质上是跨越整个Web应用程序，包括多个页面、请求和会话的一个全局作用域。</li>

			</ul>
			 
			<div class="line"></div>
			<h2>如何实现JSP或Servlet的单线程模式</h2>
			<p>对于JSP页面，可以通过page指令进行设置。
				&lt;%@page isThreadSafe=”false”%&gt;</p>
			<p>对于Servlet，可以让自定义的Servlet实现SingleThreadModel标识接口。</p>
			<p>说明：如果将JSP或Servlet设置成单线程工作模式，会导致每个请求创建一个Servlet实例，这种实践将导致严重的性能问题（服务器的内存压力很大，还会导致频繁的垃圾回收），所以通常情况下并不会这么做。</p>
			<h2>实现会话跟踪的技术有哪些</h2>
			<ol>
				<li><strong>使用Cookie</strong></li>

			</ol>
			<p>向客户端发送Cookie</p>
			<pre><code class='language-java' lang='java'>Cookie c =new Cookie(&quot;name&quot;,&quot;value&quot;); //创建Cookie 
			 c.setMaxAge(60*60*24); //设置最大时效，此处设置的最大时效为一天
			 response.addCookie(c); //把Cookie放入到HTTP响应中
			 </code></pre>
			<p>从客户端读取Cookie</p>
			<pre>
				<code class='language-java' lang='java'>String name =&quot;name&quot;; 
			 Cookie[]cookies =request.getCookies(); 
			 if(cookies !=null){ 
			    for(int i= 0;i&lt;cookies.length;i++){ 
			     Cookie cookie =cookies[i]; 
			     if(name.equals(cookis.getName())) 
			     //something is here. 
			     //you can get the value 
			     cookie.getValue(); 
			        
			    }
			  }
			 
			 </code></pre>
			<p><strong>优点:</strong> 数据可以持久保存，不需要服务器资源，简单，基于文本的Key-Value</p>
			<p><strong>缺点:</strong> 大小受到限制，用户可以禁用Cookie功能，由于保存在本地，有一定的安全风险。</p>
			<ol start='2'>
				<li>URL 重写</li>

			</ol>
			<p>在URL中添加用户会话的信息作为请求的参数，或者将唯一的会话ID添加到URL结尾以标识一个会话。 </p>
			<p><strong>优点：</strong> 在Cookie被禁用的时候依然可以使用</p>
			<p><strong>缺点：</strong> 必须对网站的URL进行编码，所有页面必须动态生成，不能用预先记录下来的URL进行访问。</p>
			<p>3.隐藏的表单域</p>
			<pre><code class='language-html' lang='html'>&lt;input type=&quot;hidden&quot; name =&quot;session&quot; value=&quot;...&quot;/&gt;
			 </code></pre>
			<p><strong>优点：</strong> Cookie被禁时可以使用</p>
			<p><strong>缺点：</strong> 所有页面必须是表单提交之后的结果。</p>
			<ol start='4'>
				<li>HttpSession</li>

			</ol>
			<p> 在所有会话跟踪技术中，HttpSession对象是最强大也是功能最多的。当一个用户第一次访问某个网站时会自动创建
				HttpSession，每个用户可以访问他自己的HttpSession。可以通过HttpServletRequest对象的getSession方
				法获得HttpSession，通过HttpSession的setAttribute方法可以将一个值放在HttpSession中，通过调用
				HttpSession对象的getAttribute方法，同时传入属性名就可以获取保存在HttpSession中的对象。与上面三种方式不同的
				是，HttpSession放在服务器的内存中，因此不要将过大的对象放在里面，即使目前的Servlet容器可以在内存将满时将HttpSession
				中的对象移到其他存储设备中，但是这样势必影响性能。添加到HttpSession中的值可以是任意Java对象，这个对象最好实现了
				Serializable接口，这样Servlet容器在必要的时候可以将其序列化到文件中，否则在序列化时就会出现异常。</p>
			<div class="line"></div>
			<h2>Cookie和Session的的区别</h2>
			<ol>
				<li>由于HTTP协议是无状态的协议，所以服务端需要记录用户的状态时，就需要用某种机制来识具体的用户，这个机制就是Session.典型的场景比如购物车，当你点击下单按钮时，由于HTTP协议无状态，所以并不知道是哪个用户操作的，所以服务端要为特定的用户创建了特定的Session，用用于标识这个用户，并且跟踪用户，这样才知道购物车里面有几本书。这个Session是保存在服务端的，有一个唯一标识。在服务端保存Session的方法很多，内存、数据库、文件都有。集群的时候也要考虑Session的转移，在大型的网站，一般会有专门的Session服务器集群，用来保存用户会话，这个时候
					Session 信息都是放在内存的，使用一些缓存服务比如Memcached之类的来放 Session。</li>
				<li>思考一下服务端如何识别特定的客户？这个时候Cookie就登场了。每次HTTP请求的时候，客户端都会发送相应的Cookie信息到服务端。实际上大多数的应用都是用 Cookie
					来实现Session跟踪的，第一次创建Session的时候，服务端会在HTTP协议中告诉客户端，需要在 Cookie 里面记录一个Session
					ID，以后每次请求把这个会话ID发送到服务器，我就知道你是谁了。有人问，如果客户端的浏览器禁用了 Cookie
					怎么办？一般这种情况下，会使用一种叫做URL重写的技术来进行会话跟踪，即每次HTTP交互，URL后面都会被附加上一个诸如 sid=xxxxx 这样的参数，服务端据此来识别用户。</li>
				<li>Cookie其实还可以用在一些方便用户的场景下，设想你某次登陆过一个网站，下次登录的时候不想再次输入账号了，怎么办？这个信息可以写到Cookie里面，访问网站的时候，网站页面的脚本可以读取这个信息，就自动帮你把用户名给填了，能够方便一下用户。这也是Cookie名称的由来，给用户的一点甜头。所以，总结一下：Session是在服务端保存的一个数据结构，用来跟踪用户的状态，这个数据可以保存在集群、数据库、文件中；Cookie是客户端保存用户信息的一种机制，用来记录用户的一些信息，也是实现Session的一种方式。</li>

			</ol>
			<p>参考：</p>
			<p><a href='https://www.zhihu.com/question/19786827/answer/28752144' target='_blank' class='url'>https://www.zhihu.com/question/19786827/answer/28752144</a></p>
			<p>《javaweb整合开发王者归来》P158 Cookie和Session的比较</p>
</div>
		</div>
		<footer>
			<p>Design by <a href="http://cdcoder.cn" target="_blank">徐思润个人博客</a> </p>
			<p>备案号：<a href="/">蜀ICP备15014105号-1</a></p>
				<script type="text/javascript" src="https://s96.cnzz.com/z_stat.php?id=1277229191&web_id=1277229191"></script>
		</footer>

	</body>
</html>
